home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / devices / msh_1_5 / part01 / src / date.c next >
C/C++ Source or Header  |  1990-02-21  |  4KB  |  168 lines

  1. /*-
  2.  * $Id: date.c,v 1.2 90/02/03 17:00:25 Rhialto Exp $
  3.  * $Log:    date.c,v $
  4.  * Revision 1.2  90/02/03  17:00:25  Rhialto
  5.  * 0x21 -> DATE_MIN
  6.  * 
  7.  * Revision 1.1  89/12/17  20:03:37  Rhialto
  8.  * Initial revision
  9.  *
  10.  * DATE.C
  11.  *
  12.  * Two date conversion routines: DateStamp <-> MSDOS date/time.
  13.  *
  14.  * This code is (C) Copyright 1989 by Olaf Seibert. All rights reserved. May
  15.  * not be used or copied without a licence.
  16.  */
  17.  
  18. #include <libraries/dos.h>
  19. #include "han.h"
  20.  
  21. #define BASEYEAR        1978
  22. #define DAYS_PER_YEAR        365
  23. #define HOURS_PER_DAY        24
  24. #define MINUTES_PER_HOUR    60
  25. #define SECONDS_PER_MINUTE  60
  26.  
  27. #define DAYS_PER_WEEK        7
  28. #define MONTHS_PER_YEAR     12
  29.  
  30. #define MINUTES_PER_DAY     (MINUTES_PER_HOUR * HOURS_PER_DAY)
  31. #define SECONDS_PER_DAY     ((long) SECONDS_PER_MINUTE * \
  32.                  MINUTES_PER_HOUR * HOURS_PER_DAY)
  33.  
  34. #define LeapYear(year)  ((year & 3) == 0)   /* From 1-Mar-1901 to 28-Feb-2100 */
  35.  
  36. int daycount[MONTHS_PER_YEAR] = {
  37.     31,    28,    31,    30,    31,    30,
  38.     31,    31,    30,    31,    30,    31
  39. };
  40.  
  41. void
  42. ToDateStamp(datestamp, date, time)
  43. struct DateStamp *datestamp;
  44. word date;
  45. word time;
  46. {
  47.     {
  48.     int hours, minutes, seconds;
  49.  
  50.     seconds = (time & 31) * 2;
  51.     time >>= 5;
  52.     minutes = time & 63;
  53.     time >>= 6;
  54.     hours = time;
  55.  
  56.     datestamp->ds_Minute = MINUTES_PER_HOUR * hours + minutes;
  57.     datestamp->ds_Tick = TICKS_PER_SECOND * seconds;
  58.     }
  59.  
  60.     {
  61.     ulong i, j, t;
  62.     int year, month, day;
  63.  
  64.     if (date < DATE_MIN)
  65.         date = DATE_MIN;
  66.  
  67.     day = date & 31;
  68.     date >>= 5;
  69.     month = (date & 15) - 1;
  70.     date >>= 4;
  71.     year = date + 1980;
  72.  
  73.     if ((unsigned)month > 11 ||
  74.         (unsigned)day > (unsigned)daycount[month]) {
  75.         day = 31;
  76.         month = 11;
  77.         year = 1979;
  78.     }
  79.  
  80.     j = year - BASEYEAR;
  81.  
  82.     /* Get the next lower full leap period (4 years and a day) since ... */
  83.     t = (year - BASEYEAR) & ~3;
  84.     i = t;
  85.     t = (t / 4) * (4 * DAYS_PER_YEAR + 1);
  86.  
  87.     /* t now is the number of days in 4 whole years since ... */
  88.  
  89.     /*dbprintf(("ly0: i=%ld(%ld) j=%ld(%ld) t=%ld\n", i, i+BASEYEAR,j,j+BASEYEAR, t));*/
  90.     while (i < j) {
  91.         /*dbprintf(("ly1: i=%ld(%ld) j=%ld(%ld) t=%ld\n", i, i+BASEYEAR,j,j+BASEYEAR, t));*/
  92.         t += DAYS_PER_YEAR;
  93.         if (LeapYear(i + BASEYEAR)) {
  94.         /*dbprintf(("leap year\n"));*/
  95.         t++;
  96.         }
  97.         i++;
  98.     }
  99.  
  100.     /* t now is the number of days in whole years since ... */
  101.  
  102.     /*dbprintf(("m0:  i=%ld j=%ld t=%ld\n", i, j, t));*/
  103.     for (i = 0; i < month; i++) {
  104.         /*dbprintf(("m1: i=%ld j=%ld t=%ld\n", i, j, t));*/
  105.         t += daycount[i];
  106.         if (i == 1 && LeapYear(year)) {
  107.         t++;
  108.         }
  109.     }
  110.  
  111.     /* t now is the number of days in whole months since ... */
  112.  
  113.     t += day - 1;
  114.  
  115.     /* t now is the number of days in whole days since ... */
  116.  
  117.     datestamp->ds_Days = t;
  118.     }
  119. }
  120.  
  121. void
  122. ToMSDate(date, time, datestamp)
  123. word *date;
  124. word *time;
  125. register struct DateStamp *datestamp;
  126. {
  127.     {
  128.     word hours, minutes, seconds;
  129.  
  130.     hours = datestamp->ds_Minute / MINUTES_PER_HOUR;
  131.     minutes = datestamp->ds_Minute % MINUTES_PER_HOUR;
  132.     seconds = datestamp->ds_Tick / TICKS_PER_SECOND;
  133.  
  134.     *time = (hours << 11) | (minutes << 5) | (seconds / 2);
  135.     }
  136.     {
  137.     register long days, i, t;
  138.     int year, month, day;
  139.  
  140.     days = datestamp->ds_Days;
  141.  
  142.     year = BASEYEAR + (days/(4*DAYS_PER_YEAR+1)) * 4;
  143.     days %= 4 * DAYS_PER_YEAR + 1;
  144.     while (days) {
  145.         t = DAYS_PER_YEAR;
  146.         if (LeapYear(year))
  147.             t++;
  148.         if (days < t)
  149.             break;
  150.         days -= t;
  151.         year++;
  152.     }
  153.     days++;
  154.     for (i = 0; i < MONTHS_PER_YEAR; i++) {
  155.         t = daycount[i];
  156.         if (i == 1 && LeapYear(year))
  157.             t++;
  158.         if (days <= t)
  159.             break;
  160.         days -= t;
  161.     }
  162.     month = i + 1;
  163.     day = days;
  164.  
  165.     *date = ((year - 1980) << 9) | (month << 5) | day;
  166.     }
  167. }
  168.